#include <iostream>
#include <fstream> 
#include <winsock.h>
#include <wsipv6ok.h>
#include <string>
#include <set>
#include <vector>
#include <map>
using namespace std;

enum emA
{
	eA = 0,
	eB = 1,
	eC = 2,
};

template <typename T>
struct TAutoZeroMem
{
	TAutoZeroMem()
	{
		::memset(static_cast<T*>(this), 0, sizeof(T));
	}
};


struct tA:public TAutoZeroMem<tA>

{
	emA e;
	int a;
	int b;
	int c;
	string s;
	tA()
	{
		a = 1;
	}
};

class Account
{
public:
	Account(double dAmount, const string& sOwner)
	{
		cout<<"Account constructor "<<dAmount<<"\t"<<sOwner<<"\n";
		m_dAmount = dAmount;
		m_sOwner = sOwner;
	}
	~Account()
	{
		cout<<"Account destructor "<<m_dAmount<<"\t"<<m_sOwner<<"\n";
	}
private:
	double m_dAmount;
	string m_sOwner;
	static double s_dInterestRate;
	static const string sc_sName;
	static const int sc_nNameSize = 16;
	static const char sc_szName[sc_nNameSize];

public:
	inline double Account::DailyReturn()
	{
		return (s_dInterestRate / 365 * m_dAmount);
	}
	string GetOwner() {return m_sOwner;}
	static void RaiseInterest(double dIncr);
	static double GetInterest() {return s_dInterestRate;}

private:
	friend int CompareRevenue(Account&, Account*);
};

double Account::s_dInterestRate = 0.5;
const string Account::sc_sName("zzz");
const char Account::sc_szName[sc_nNameSize] = "zzz";

void Account::RaiseInterest(double dIncr)
{
	s_dInterestRate += dIncr;
}

int CompareRevenue(Account& ac1, Account* ac2)
{
	double dRet1, dRet2;
	dRet1 = ac1.s_dInterestRate * ac1.m_dAmount;
	dRet2 = ac2->s_dInterestRate * ac2->m_dAmount;

	return dRet1 > dRet2;
}

bool LimitInterest(double dRate)
{
	return dRate <= Account::GetInterest();
}

void main(void)
{
	double dLimit = 0.5;
	if (LimitInterest(dLimit))
	{
		void (*psf)(double) = &Account::RaiseInterest;
		psf(0.2);
	}

	Account ac1(100, "zzz");
	Account ac2(200, "ccc");
	if (CompareRevenue(ac1, &ac2) > 0)
	{
		cout<<ac1.GetOwner()<<" is richer than "<<ac2.GetOwner()<<".\n";
	}
	else
	{
		cout<<ac1.GetOwner()<<" is poorer than "<<ac2.GetOwner()<<".\n";
	}

	//Test constructor and destructor function
	Account a1(1, "a1");
	Account& ra = a1;
	Account* pa = 0;
	Account a2(2, "a2");
	pa = new Account(3, "pa");
	delete pa;

	//cout<<true<<endl;

	string strLookType = "36001_2_3_4";
	int nPos = strLookType.find("_");
	string strType = nPos == string::npos ? "0" : strLookType.substr(nPos+1, sizeof(strLookType));
	int nType = atoi(strType.c_str());
	string strLook = strLookType.substr(0, nPos);
	int nPos2 = strLookType.find("_", nPos+1);

	cout<<nPos<<"\t"<<strType<<"\t"<<nType<<"\t"<<strLook<<endl;

	struct TTT
	{
		int i;
		string s;
		TTT()
		{
			i = 0;
			s = "";
		}

		bool operator<(const TTT& t) const
		{
			return i < t.i;
		}
	};	
	
	TTT t1;
	t1.i = 1;
	t1.s = "111";
	TTT t2;
	t2.i = 2;
	t2.s = "222";
	TTT t3;
	t3.i = 3;
	t3.s = "333";

	vector<TTT> vTest;
	vTest.push_back(t1);
	vTest.push_back(t2);
	vTest.push_back(t3);

	int n = vTest.size();
	for (vector<TTT>::iterator iter = vTest.begin(); iter != vTest.end(); ++iter)
	{
		cout<<(*iter).i<<"\t"<<(*iter).s<<endl;
	}

	set<TTT> sTest(vTest.begin(), vTest.end());

	for (set<TTT>::iterator iter = sTest.begin(); iter != sTest.end(); ++iter)
	{
		cout<<(*iter).i<<"\t"<<(*iter).s<<endl;
	}
	

	map<string, int> mapTest;
	mapTest["111"] = 1;
	mapTest["222"] = 2;

	int nnn = 33333;
	nnn = nnn / 10 * 10;

	int ttttttttttttttt = 1;
}
